package services

import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var qcCopyAccountLogger *logrus.Logger

// InitQcAccountCopyLogger 移除 init() 函数，改为显式初始化函数
func InitQcAccountCopyLogger() {
	// 确保在 common 初始化后调用
	qcCopyAccountLogger = core.InitLogger(common.LogsErrorMap[16])
}

// HugeQcCopyAccount 消息结构体
type HugeQcCopyAccount struct {
	AccountName       string
	MerchantID        string
	AccountID         string
	WithoutID         int64
	Contact           string
	MobilePhoneNumber string
	Email             string
	CopyNumber        int
	Person            string
}

// 校验店铺是否授权返回参数
type checkAgentResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Total int                 `json:"total"`
		List  []checkDataResponse `json:"data"`
	} `json:"data"`
}

type checkDataResponse struct {
	Id               int    `json:"id"`
	ShopName         string `json:"shopName"`
	AuthorizedStatus int    `json:"authorizedStatus"`
	ShopId           int    `json:"shopId"`
}

// 添加账号状态映射
var accountQcStatus = map[int]string{
	1: "授权中",
	2: "已拒绝",
	4: "已授权",
	8: "已关闭",
}

// 历史账户信息
type companyNameResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Total int               `json:"total"`
		List  []companyListData `json:"data"`
	} `json:"data"`
}

type companyListData struct {
	LicenseProvince string `json:"licenseProvince"`
	LicenseCity     string `json:"licenseCity"`
}

// 公司名称
type getQualificationResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Type        int    `json:"type"`
		BussinessNo string `json:"bussinessNo"`
		CompanyName string `json:"companyName"`
	} `json:"data"`
}

type HugeQcCopyAccountService struct{}

func (s *HugeQcCopyAccountService) Handle(msgId int, subjectName, roomId string, content []string, jobId uint64) error {

	var msg = &models.Msg{}

	fmt.Println("qcCopyAccountLogger", "原始结构Id：", msgId)
	// 获取数据
	err := common.DB.Where("id = ?", msgId).First(&msg).Error
	if err != nil {
		qcCopyAccountLogger.Error("巨量千川获取数据失败", common.LogsErrorMap[2], msgId, err)
		return errors.New("巨量千川获取数据失败：" + err.Error())
	}

	qcCopyAccountLogger.Info("qcCopyAccountLogger", "原始结构：", content)

	// 处理需要的数据结构
	result, err := s.analyzeContent(content)
	if err != nil {
		qcCopyAccountLogger.Error(err)
		return errors.New("解析失败：" + err.Error())
	}

	// 移除功能行
	msg.Content = RemoveTitle(msg)
	qcCopyAccountLogger.Info("qcCopyAccountLogger", result, "移除后的结构：", msg, "广告主信息：", content)

	if result.CopyNumber > 10 {
		return errors.New("复制数量不能大于10个")
	}

	rdb := core.InitRedis(13)
	ctx := context.Background()

	cookies, err := rdb.Get(ctx, "laravel_database_oead_adv_cookies").Result()
	var successResponse []string
	for i := 0; i < result.CopyNumber; i++ {

		var qc models.ImportOeqc
		err := common.DBDk.Where("account_id = ? AND is_old = 1", result.AccountID).Take(&qc).Error
		if err != nil {
			adCopyAccountTxLogger.Warnf("OA不存在ID: %s", result.AccountID)
			return errors.New("OA千川不存在ID" + err.Error())
		}

		// 第一步 校验店铺是否授权
		err = s.checkAuthorization(result.MerchantID, cookies)
		if err != nil {
			qcCopyAccountLogger.Error("校验店铺授权", common.LogsErrorMap[2], result.MerchantID, err)
			return fmt.Errorf("媒体提示1：%v", err)
		}
		// 第二步 根据商家ID 获取公司名称
		companyInfo, err := s.getCompanyNameHistory(result.AccountID, cookies)
		if err != nil {
			qcCopyAccountLogger.Error("获取公司名称", common.LogsErrorMap[2], result.AccountName, err)
			return fmt.Errorf("媒体提示2：%v", err)
		}
		qcCopyAccountLogger.Info("第二步获取的信息：", companyInfo)

		// 第三步 获取最大开户数量和当前开户数量
		getCompanyOpenMax, err := s.getCheckCompany(4, result.AccountName, cookies)
		if err != nil {
			qcCopyAccountLogger.Error("获取最大开户数量和当前开户数量", err.Error())
			return fmt.Errorf("媒体提示3：%v", err)
		}
		qcCopyAccountLogger.Infof("获取成功后的账户名称: %v", getCompanyOpenMax)

		// 第四步 获取证件号码
		documentInfo, err := s.getDocumentNumber(result.MerchantID, cookies)
		if err != nil {
			qcCopyAccountLogger.Warnf("获取证件号码失败: %v", err)
			return errors.New("获取证件号码失败：" + err.Error())
		}

		qcCopyAccountLogger.Infof("获取证件号码成功: %v", documentInfo)

		// 第五步 获取直客信息
		searchResponse, err := s.getSearchWithout(documentInfo.Data.CompanyName, documentInfo.Data.BussinessNo, cookies, documentInfo.Data.Type)
		if err != nil {
			qcCopyAccountLogger.Warnf("获取直客信息失败: %v", err)
			return errors.New("获取直客信息失败：" + err.Error())
		}

		var industryId int64
		var smallIndustryId int64
		for _, value := range searchResponse.Data {
			if value.CustomerID == result.WithoutID {
				industryId = value.IndustryId
				smallIndustryId = value.SmallIndustryId
				break
			}
		}

		if industryId == 0 || smallIndustryId == 0 {
			return errors.New("一二级行业未找到")
		}

		makeData := map[string]interface{}{
			"agentId":              "1697705553915912",
			"name":                 getCompanyOpenMax,
			"eshopAccountType":     1,
			"company":              result.AccountName,
			"license_type":         documentInfo.Data.Type,
			"license_no":           documentInfo.Data.BussinessNo,
			"contacter":            result.Contact,
			"phonenumber":          result.MobilePhoneNumber,
			"email":                result.Email,
			"shopId":               result.MerchantID,
			"accountCate":          4,
			"second_industry_code": smallIndustryId,
			"first_industry_code":  industryId,
			"license_country":      17487275,
			"license_country_name": "中国",
			"license_province":     companyInfo.LicenseProvince,
			"license_city":         companyInfo.LicenseCity,
			"systemOrigin":         "103",
		}

		qcCopyAccountLogger.Info("组装提交数据：", makeData)

		// 同意开户
		createSuccess, err := s.createFirstState(makeData, cookies)
		if err != nil {
			qcCopyAccountLogger.Error("提交开户数据失败：", err)
			return errors.New("开户失败" + err.Error())
		}

		// 将开户成功的记录下来
		successResponse = append(successResponse, createSuccess.AdvId)
		// 将开户信息记录到 copy_account_list 表中
		accountID, _ := strconv.Atoi(createSuccess.AdvId)
		parentAccountID, _ := strconv.Atoi(result.AccountID)

		createCopy := &models.CopyAccountList{
			Parent:       parentAccountID,
			AccountID:    accountID,
			AccountName:  createSuccess.AdvName,
			HandleStatus: 1,
			Type:         5,
			Username:     result.Person,
		}

		err = common.DB.Create(createCopy).Error
		if err != nil {
			qcCopyAccountLogger.Errorf("数据入库异常: %v, 数据: %v", err, createCopy)
			return errors.New("数据入库异常，请检查日志: " + err.Error())
		}

	}
	if len(successResponse) > 0 {
		if err := BendiSendText(msg.Content+"\n-----------------------------------\n复制成功："+strings.Join(successResponse, ","), msg.RoomID, msg.Sender); err != nil {
			qcCopyAccountLogger.Errorf("复制成功发送消息失败: %v", err)
			return errors.New("复制成功发送消息失败: " + err.Error())
		}
	}
	return nil
}

// 同意开户
func (s *HugeQcCopyAccountService) createFirstState(data map[string]interface{}, cookies string) (*createResponseData, error) {
	createUrl := "https://agent.oceanengine.com/agent/adv-create/add/first/state/"

	var createRes createResponse
	err := s.SendCurlRequest(createUrl, data, cookies, "POST", "", &createRes)
	if err != nil {
		qcCopyAccountLogger.Infof("createFirstState请求失败: %v", err)
		return nil, fmt.Errorf("创建开户失败1: %v", err)
	}

	qcCopyAccountLogger.Info("createFirstState原始响应: %+v", createRes)

	if createRes.Code != 0 {
		qcCopyAccountLogger.Info("createRes.Code:", createRes.Msg, "返回参数:", createRes)
		return nil, fmt.Errorf("创建开户失败2: %v", createRes.Msg)
	}

	var res createResponseData
	err = json.Unmarshal(createRes.Data, &res)
	if err != nil {
		return nil, fmt.Errorf("创建开户失败3解析失败: %v", err)
	}

	if res.ErrorState != 0 {
		qcCopyAccountLogger.Info("ErrorState:", res.Msg, "返回参数:", res)
		return nil, fmt.Errorf("创建开户失败3: %v", res.Msg)
	}

	return &res, nil
}

// 获取直客信息
func (s *HugeQcCopyAccountService) getSearchWithout(customerName, licenseNo, oeAdCookies string, licenseType int) (*SearchWithoutResponse, error) {
	sprintfUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/customer/query/?customerName=%s&isQianchuan=true&licenseNo=%s&licenseType=%d", customerName, licenseNo, licenseType)

	var response SearchWithoutResponse
	err := s.SendCurlRequest(sprintfUrl, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		qcCopyAccountLogger.Errorf("获取直客信息失败: %v", err)
		return nil, err
	}

	// 记录完整响应
	qcCopyAccountLogger.Infof("getSearchWithout获取直客完整信息: %+v", response)

	// 检查返回码不为0的情况
	if response.Code != 0 {
		qcCopyAccountLogger.Warnf("getSearchWithout获取直客信息失败: %s", response.Msg)
		return nil, fmt.Errorf("接口返回错误: %s", response.Msg)
	}

	// 检查data为空的情况
	if len(response.Data) == 0 {
		qcCopyAccountLogger.Warnf("getSearchWithout未找到对应的授权信息: %s", response.Msg)
		return nil, fmt.Errorf("未找到直客信息: %s", response.Msg)
	}

	return &response, nil
}

// 获取证件号码
func (s *HugeQcCopyAccountService) getDocumentNumber(lifeAccountId, cookies string) (*getQualificationResponse, error) {
	numUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/optimize/eshop/get-qualification?eshopAccountType=1&shopId=%s", lifeAccountId)

	var req getQualificationResponse

	err := s.SendCurlRequest(numUrl, nil, cookies, "GET", "", &req)
	if err != nil {
		qcCopyAccountLogger.Error("获取证件号码失败1", err)
		return nil, errors.New("获取证件号码失败1" + err.Error())
	}

	qcCopyAccountLogger.Info("获取证件号码成功", req)

	if req.Code != 0 {
		qcCopyAccountLogger.Error("获取证件号码失败2", req)
		return nil, fmt.Errorf("获取证件号码失败2: %s", req.Msg)
	}

	return &req, nil
}

// 获取最大开户数量和当前开户数量
func (s *HugeQcCopyAccountService) getCheckCompany(num int, accountName, cookies string) (string, error) {
	checkUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/name/check/?accountCate=%d&advName=%s", num, accountName)

	var copyRes checkCopyResponse
	err := s.SendCurlRequest(checkUrl, nil, cookies, "GET", "", &copyRes)
	if err != nil {
		qcCopyAccountLogger.Error("发送复制请求失败1:", err, "返回结果：", copyRes)
		return "", fmt.Errorf("发送复制请求失败1: %v", err)
	}

	qcCopyAccountLogger.Info("复制请求结果:", copyRes)

	businessName := accountName

	// 无限循环处理重复名称
	for {
		if copyRes.Msg == "千川账户名称重复，请修改后提交" {
			// 使用正则表达式匹配名称
			re := regexp.MustCompile(`^(.*?)-yx(-\d+)?$`)
			matches := re.FindStringSubmatch(businessName)

			if len(matches) > 0 {
				baseName := matches[1]
				var suffixNum int
				if matches[2] != "" {
					num, _ := strconv.Atoi(matches[2][2:]) // 去掉前面的 "-yx-" 前缀
					suffixNum = num + 1
				} else {
					suffixNum = 1
				}
				businessName = fmt.Sprintf("%s-yx-%d", baseName, suffixNum)
			} else {
				// 首次添加后缀
				businessName = fmt.Sprintf("%s-yx-1", businessName)
			}

			// 更新公司名称进行下一次检查
			checkUrl = fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/name/check/?accountCate=%d&advName=%s", num, businessName)
			err = s.SendCurlRequest(checkUrl, nil, cookies, "GET", "", &copyRes)
			if err != nil {
				qcCopyAccountLogger.Error("发送复制请求失败2:", err, "返回结果：", copyRes)
				return "", fmt.Errorf("发送复制请求失败2: %v", err)
			}
		} else {
			break
		}
	}

	return businessName, nil
}

// 根据商家ID 获取公司名称
func (s *HugeQcCopyAccountService) getCompanyNameHistory(lifeAccountId, cookie string) (*companyListData, error) {
	historyUrl := "https://agent.oceanengine.com/agent/eshop/list/?advId=" + lifeAccountId + "&page=1&size=10"

	var req companyNameResponse

	err := s.SendCurlRequest(historyUrl, nil, cookie, "GET", "", &req)
	if err != nil {
		qcCopyAccountLogger.Errorf("获取企业历史记录: %v", err)
		return nil, fmt.Errorf("获取企业历史记录" + err.Error())
	}

	qcCopyAccountLogger.Info("记录完整的返回信息：", req)

	if req.Code != 0 {
		qcCopyAccountLogger.Error("获取公司名称历史失败curl!=0:", req)
		return nil, fmt.Errorf("公司名称历史失败" + req.Msg)
	}

	return &companyListData{
		LicenseProvince: req.Data.List[0].LicenseProvince,
		LicenseCity:     req.Data.List[0].LicenseCity,
	}, nil
}

// 校验店铺是否授权
func (s *HugeQcCopyAccountService) checkAuthorization(lifeAccountId, cookie string) error {
	checkUrl := "https://agent.oceanengine.com/agent/optimize/eshop/list-eshop?page=1&shopId=" + lifeAccountId + "&size=10"

	var req checkAgentResponse
	err := s.SendCurlRequest(checkUrl, nil, cookie, "GET", "", &req)
	if err != nil {
		qcCopyAccountLogger.Errorf("checkAuthorization获取商家是否授权: %v", err)
		return errors.New("未获取到授权信息：" + err.Error())
	}

	if req.Code != 0 {
		qcCopyAccountLogger.Errorf("返回Code不为0: %v", err)
		return errors.New("返回Code不为0：" + err.Error())
	}

	if req.Data.Total == 0 {
		qcCopyAccountLogger.Errorf("返回Code不为0: %v", err)
		return errors.New("媒体后台中未查询到授权信息：" + err.Error())
	}

	shop := req.Data.List[0]
	if shop.AuthorizedStatus != 4 {
		statusName := "未知状态"
		if name, ok := accountQcStatus[shop.AuthorizedStatus]; ok {
			statusName = name
		}
		return fmt.Errorf("账号 %s  授权状态：%s", lifeAccountId, statusName)
	}
	return nil
}

// SendCurlRequest 发送HTTP请求
func (s *HugeQcCopyAccountService) SendCurlRequest(url string, postData interface{}, xhsCookies string, method string, oeCsrfToken string, result interface{}) error {
	// 创建请求上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 序列化POST数据
	var bodyReader io.Reader
	if postData != nil {
		jsonData, err := json.Marshal(postData)
		if err != nil {
			return fmt.Errorf("JSON序列化失败: %v", err)
		}
		bodyReader = bytes.NewBuffer(jsonData)
	}

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Cookie", xhsCookies)
	if oeCsrfToken != "" {
		req.Header.Set("Cg-Csrf-Token", oeCsrfToken)
	}

	// 创建自定义客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应失败: %v", err)
	}

	qcCopyAccountLogger.Info("获取后得参数格式：", string(respBody))

	if result != nil {
		if err := json.Unmarshal(respBody, &result); err != nil {
			return fmt.Errorf("JSON解析失败: %v", err)
		}
	}
	return nil
}

// analyzeContent 解析内容为广告主信息数组
func (s *HugeQcCopyAccountService) analyzeContent(content []string) (*HugeQcCopyAccount, error) {
	// 初始化结果变量
	var accountName string
	var merchantID string
	var accountID string
	var withoutIDStr string
	var withoutID int64
	var contact string
	var mobilePhoneNumber string
	var email string
	var copyNumber int
	var person string

	// 遍历内容行
	for _, line := range content {
		// 账户名称
		if strings.HasPrefix(line, "账户名称:") {
			accountName = strings.TrimSpace(strings.TrimPrefix(line, "账户名称:"))
		}
		// 商家ID
		if strings.HasPrefix(line, "商家ID:") {
			merchantID = strings.TrimSpace(strings.TrimPrefix(line, "商家ID:"))
		}
		// OA账户ID
		if strings.HasPrefix(line, "OA账户ID:") {
			accountID = strings.TrimSpace(strings.TrimPrefix(line, "OA账户ID:"))
		}
		// 直客ID
		if strings.HasPrefix(line, "直客ID:") {
			withoutIDStr = strings.TrimSpace(strings.TrimPrefix(line, "直客ID:"))
		}
		// 联系人姓名
		if strings.HasPrefix(line, "联系人姓名:") {
			contact = strings.TrimSpace(strings.TrimPrefix(line, "联系人姓名:"))
		}
		// 手机号
		if strings.HasPrefix(line, "手机号:") {
			mobilePhoneNumber = strings.TrimSpace(strings.TrimPrefix(line, "手机号:"))
		}
		// 邮箱
		if strings.HasPrefix(line, "邮箱:") {
			email = strings.TrimSpace(strings.TrimPrefix(line, "邮箱:"))
		}
		// 复制数量
		if strings.HasPrefix(line, "复制数量:") {
			strValue := strings.TrimSpace(strings.TrimPrefix(line, "复制数量:"))
			if strValue != "" {
				var err error
				copyNumber, err = strconv.Atoi(strValue)
				if err != nil {
					qcCopyAccountLogger.Errorf("复制数量转换失败: %v", err)
					return nil, fmt.Errorf("复制数量格式错误: %w", err)
				}
			}
		}
		// 媒介姓名
		if strings.HasPrefix(line, "媒介姓名:") {
			person = strings.TrimSpace(strings.TrimPrefix(line, "媒介姓名:"))
		}
	}

	if accountName == "" || accountID == "" || merchantID == "" || contact == "" || email == "" || mobilePhoneNumber == "" || person == "" || withoutIDStr == "" || copyNumber == 0 {
		qcCopyAccountLogger.Warn("请检查参数是否正确")
		return nil, errors.New("解析参数失败: 请检查参数是否正确")
	}

	// 转换 withoutID 为 int64
	var err error
	withoutID, err = strconv.ParseInt(withoutIDStr, 10, 64)
	if err != nil {
		localCopyAccountLogger.Errorf("直客ID转换失败: %v", err)
		return nil, fmt.Errorf("直客ID格式错误: %w", err)
	}

	return &HugeQcCopyAccount{
		AccountName:       accountName,
		MerchantID:        merchantID,
		AccountID:         accountID,
		WithoutID:         withoutID,
		Contact:           contact,
		MobilePhoneNumber: mobilePhoneNumber,
		Email:             email,
		Person:            person,
		CopyNumber:        copyNumber,
	}, nil
}
